package com.asa.common.ext

import android.graphics.Bitmap
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
import androidx.annotation.DimenRes
import androidx.core.content.ContextCompat
import androidx.databinding.BindingAdapter
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import androidx.viewpager.widget.ViewPager
import androidx.viewpager2.widget.ViewPager2
import com.asa.common.net.NetModel
import com.asa.common.viewmodel.BaseMultiItemViewModel
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CircleCrop
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.RequestOptions
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter
import java.lang.Exception

/**
 *  点击抖动
 */
fun View.setOnSingleClickListener(delayMillis:Long =1000, onClick:(view:View)->Any?){
    this.setOnClickListener {
        this.isClickable = false
        onClick.invoke(this)
        postDelayed({
            this.isClickable = true
        },delayMillis)
    }
}


@BindingAdapter(value = ["onSingleClick"], requireAll = false)
fun View.onSingleClick(onSingleClick: (view: View)->Unit) {
    val minTime = 1000L
    var lastTime = 0L
    setOnClickListener {
        val tmpTime = System.currentTimeMillis()
        if (tmpTime - lastTime > minTime) {
            onSingleClick.invoke(it)
            lastTime = tmpTime
        }
    }
}


@BindingAdapter(value = ["viewWidth","viewHeight"],requireAll = true)
fun View.setLayoutParams(viewWidth:Float = -1f,viewHeight:Float = -1f){
    val layoutParams = layoutParams?:ViewGroup.LayoutParams(viewWidth.toInt(),viewHeight.toInt())
    layoutParams.height = when(viewHeight){
        -1f -> ViewGroup.LayoutParams.WRAP_CONTENT
        -2f -> ViewGroup.LayoutParams.MATCH_PARENT
        else -> viewHeight.toInt()
    }
    layoutParams.width = when(viewWidth){
        -1f -> ViewGroup.LayoutParams.WRAP_CONTENT
        -2f -> ViewGroup.LayoutParams.MATCH_PARENT
        else -> viewWidth.toInt()
    }
    this.layoutParams = layoutParams
}

/**
 * direction  1 2 4 8  左上右下
 */
@BindingAdapter(value = ["drawableResId","direction"],requireAll = true)
fun TextView.setDrawable(drawableResId:Int,direction:Int){
    if (drawableResId == 0){
        setCompoundDrawables(null,null,null,null)
        return
    }
    val drawable = ContextCompat.getDrawable(context,drawableResId)
    drawable?.setBounds(0,0,drawable.minimumWidth,drawable.minimumHeight)
    when(direction){
        1-> setCompoundDrawablesWithIntrinsicBounds(drawable,null,null,null)
        2-> setCompoundDrawablesWithIntrinsicBounds(null,drawable,null,null)
        4-> setCompoundDrawablesWithIntrinsicBounds(null,null,drawable,null)
        8-> setCompoundDrawablesWithIntrinsicBounds(null,null,null,drawable)
    }
}


/**
 *  设置 TextView 携带的drawable 的宽高属性
 */
@BindingAdapter(value = ["textDrawableWidth","textDrawableHeight"],requireAll = true)
fun TextView.setDrawableWidthAndHeight(textDrawableWidth:Float,textDrawableHeight:Float){
    val compoundDrawables = compoundDrawables
    val leftDrawable = compoundDrawables[0]
    val topDrawable = compoundDrawables[1]
    val rightDrawable = compoundDrawables[2]
    val bottomDrawable = compoundDrawables[3]
    leftDrawable?.setBounds(0,0,textDrawableWidth.toInt(),textDrawableHeight.toInt())
    topDrawable?.setBounds(0,0,textDrawableWidth.toInt(),textDrawableHeight.toInt())
    rightDrawable?.setBounds(0,0,textDrawableWidth.toInt(),textDrawableHeight.toInt())
    bottomDrawable?.setBounds(0,0,textDrawableWidth.toInt(),textDrawableHeight.toInt())
}

/**
 *  设置textView的基本属性   颜色和字体大小
 */
@BindingAdapter(value = ["textColorId","textSizeId"],requireAll = false)
fun TextView.setTextViewParams(@ColorRes textColorId:Int, @DimenRes textSizeId:Int){
    setTextColor(ContextCompat.getColor(context,textColorId))
    if (textSizeId != -1 &&textSizeId != 0){
        setTextSize(TypedValue.COMPLEX_UNIT_PX,context.resources.getDimension(textSizeId))
    }
}

/**
 *  设置 view 的margin属性
 */
@BindingAdapter(value = ["marginDirection","viewMargin"],requireAll = true)
fun View.setViewMargin(marginDirection:Int,viewMargin:Int){
    val layoutParams : ViewGroup.LayoutParams = layoutParams ?: return
    if (layoutParams is ViewGroup.MarginLayoutParams){
        val leftMargin = layoutParams.leftMargin
        val topMargin = layoutParams.topMargin
        val rightMargin = layoutParams.rightMargin
        val bottomMargin = layoutParams.bottomMargin
        when(marginDirection){
            1-> layoutParams.setMargins(viewMargin,topMargin,right,bottom)
            2-> layoutParams.setMargins(leftMargin,viewMargin,rightMargin,bottomMargin)
            4-> layoutParams.setMargins(leftMargin,topMargin,viewMargin,bottomMargin)
            8-> layoutParams.setMargins(leftMargin,topMargin,rightMargin,viewMargin)
        }
    }
}

/**
 *  glide 设置imageView
 */
@BindingAdapter(value = ["source","placeHolder","isCircleCrop","roundingRadius"],requireAll = false)
fun ImageView.setImage(source:Any?,placeHolder:Any?,isCircleCrop:Boolean = false,roundingRadius : Float = 0f){
    val requestManager = Glide.with(context)
    var requestBuilder =  when(source){
        is String -> {
            if (source.endsWith(".gif")){
                requestManager.asGif().load(source)
            } else{
                requestManager.load(source)
            }
        }
        is Int ->requestManager.load(source)
        is Drawable -> requestManager.load(source)
        is Bitmap -> requestManager.load(source)
        else-> requestManager.load("")
    }
    if (placeHolder != null){
        if (placeHolder is Drawable){
            requestBuilder = requestBuilder.apply(RequestOptions.placeholderOf(placeHolder))
        } else if (placeHolder is Int){
            requestBuilder = requestBuilder.apply(RequestOptions.placeholderOf(placeHolder))
        }
    }
    if (isCircleCrop){
        requestBuilder = requestBuilder.apply(RequestOptions.bitmapTransform(CircleCrop()))
    }
    if (roundingRadius > 0f){
        requestBuilder = requestBuilder.apply(RequestOptions.bitmapTransform(RoundedCorners(roundingRadius.toInt())))
    }
    requestBuilder.into(this)
}


/**
 *  viewPager 切换 tab
 */
@BindingAdapter(value = ["pagePos","smoothScroll"],requireAll = true)
fun ViewPager2.switchPage(pagePos:Int,smoothScroll:Boolean){
    setCurrentItem(pagePos,smoothScroll)
}


/**
 *  viewPager 切换 tab
 */
@BindingAdapter(value = ["pagePos","smoothScroll"],requireAll = true)
fun ViewPager.switchPage(pagePos:Int, smoothScroll:Boolean){
    setCurrentItem(pagePos,smoothScroll)
}


/**
 * scrollBottomCallback:  滚动到底部回调函数
 * bottomOffset: 滚动到底部变异量
 */
@BindingAdapter(value = ["scrollBottomCallback","bottomOffset"],requireAll = true)
fun RecyclerView.setScrollBottomListener(scrollBottomCallback:()->Unit,bottomOffset:Int = 3){
    addOnScrollListener(object :RecyclerView.OnScrollListener(){
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
            if (recyclerView.layoutManager !is LinearLayoutManager)return
            val manager = recyclerView.layoutManager as LinearLayoutManager?
            val findLastVisibleItemPosition = manager!!.findLastVisibleItemPosition()
            val itemCount = manager.itemCount
            checkLoadMore(findLastVisibleItemPosition,itemCount)
        }

        @Synchronized
        private fun checkLoadMore(findLastVisibleItemPosition: Int, itemCount: Int) {
            if (findLastVisibleItemPosition >  itemCount - bottomOffset){
                scrollBottomCallback.invoke()
            }
        }
    })
}

/**
 *
 */
@BindingAdapter(value=["scrollListener"])
fun RecyclerView.addScrollListener(scrollStateListener:(newStatus:Int,firstVisibleItemPosition:Int)->Unit){
    addOnScrollListener(object :RecyclerView.OnScrollListener(){
        var state = RecyclerView.SCROLL_STATE_IDLE
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
            state = newState
            var firstVisibleItemPosition = 0
            val layoutManager = recyclerView.layoutManager
            if (layoutManager is LinearLayoutManager){
                firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
            } else if (layoutManager is StaggeredGridLayoutManager){
                val intArray = layoutManager.findFirstVisibleItemPositions(null)
                firstVisibleItemPosition = intArray[0]
            }
            scrollStateListener.invoke(state,firstVisibleItemPosition)
        }

        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)
            var firstVisibleItemPosition = 0
            val layoutManager = recyclerView.layoutManager
            if (layoutManager is LinearLayoutManager){
                firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
            } else if (layoutManager is StaggeredGridLayoutManager){
                val intArray = layoutManager.findFirstVisibleItemPositions(null)
                firstVisibleItemPosition = intArray[0]
            }
            scrollStateListener.invoke(state,firstVisibleItemPosition)
        }
    })
}

@BindingAdapter(value = ["isSelected"], requireAll = false)
fun View.setParams(selectedState: Boolean) {
    isSelected = selectedState
}

@BindingAdapter(value = ["horizontalSpacing","verticalSpacing"],requireAll = false)
fun RecyclerView.setItemSpacing(horizontalSpacing:Float,verticalSpacing:Float){
    addItemDecoration(object :RecyclerView.ItemDecoration(){
        override fun getItemOffsets(
            outRect: Rect,
            view: View,
            parent: RecyclerView,
            state: RecyclerView.State
        ) {
            super.getItemOffsets(outRect, view, parent, state)
            val position = parent.getChildAdapterPosition(view)
            if (parent.layoutManager is StaggeredGridLayoutManager){
                val spanCount = (parent.layoutManager as StaggeredGridLayoutManager).spanCount
                when(spanCount){
                    2->{
                        val sp = (horizontalSpacing/2).toInt()
                        if (position % 2 == 0){
                            outRect.right = sp
                        }else{
                            outRect.left = sp
                        }
                    }
                    3->{
                        val sp = (horizontalSpacing / 3).toInt()
                        when {
                            position % 3 == 0 -> {
                                outRect.left = 0
                                outRect.right = sp * 2
                            }
                            position % 3 == 1 -> {
                                outRect.left = sp
                                outRect.right = sp
                            }
                            else -> {
                                outRect.left = sp * 2
                                outRect.right = 0
                            }
                        }
                    }
                }
                var verticalSpace = verticalSpacing
                if (adapter is BindingRecyclerViewAdapter<*>){
                    try {
                        val adapter = adapter as BindingRecyclerViewAdapter<BaseMultiItemViewModel<out NetModel>>
                        if (adapter.getAdapterItem(position).itemType == 7){
                            verticalSpace = verticalSpacing/3f * 2f
                            outRect.top = (verticalSpace).toInt()
                        }
                    }catch (e: Exception){
                        e.printStackTrace()
                    }
                }
                outRect.bottom = (verticalSpacing).toInt()
            }else if (parent.layoutManager is GridLayoutManager){
                val spanCount = (parent.layoutManager as GridLayoutManager).spanCount
                when(spanCount){
                    2->{
                        val sp = (horizontalSpacing/2).toInt()
                        if (position % 2 == 0){
                            outRect.right = sp
                        }else{
                            outRect.left = sp
                        }
                    }
                    3->{
                        val sp = (horizontalSpacing / 3).toInt()
                        when {
                            position % 3 == 0 -> {
                                outRect.left = 0
                                outRect.right = sp * 2
                            }
                            position % 3 == spanCount-1 -> {
                                outRect.left = sp * 2
                                outRect.right = 0
                            }
                            else -> {
                                outRect.left = sp
                                outRect.right = sp
                            }
                        }
                    }
                }
                outRect.bottom = (verticalSpacing).toInt()
            }else if (parent.layoutManager is LinearLayoutManager){
                outRect.left = (horizontalSpacing / 2).toInt()
                outRect.right = (horizontalSpacing / 2).toInt()
                if (position >= 1) outRect.top = verticalSpacing.toInt()
            }
        }
    })
}


